package com.be.beadmin.material.controller;

import com.alibaba.excel.EasyExcel;
//import com.alibaba.fastjson2.JSON;
//import com.alibaba.fastjson2.JSONObject;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.common.utils.ResponseUtil;
import com.be.beadmin.common.utils.ResultModel;
import com.be.beadmin.material.dto.input.PurchaseOrderDto;
import com.be.beadmin.material.dto.output.PurchaseOrderEx;
import com.be.beadmin.material.dto.output.PurchaseOrderTotalExcelEx;
import com.be.beadmin.material.dto.output.PurchaseOrderTotalExcelEx;
import com.be.beadmin.material.entity.PurchaseOrderTotal;
import com.be.beadmin.material.service.PurchaseOrderService;
import com.be.beadmin.product.dto.output.WorkOrderInforEx;
import com.be.beadmin.product.entity.WorkOrderInfor;
import com.be.beadmin.product.repository.WorkOrderInforRepository;
import com.be.beadmin.product.service.WorkHoursRequestService;
import com.be.beadmin.product.service.WorkOrderInforService;
import com.be.beadmin.service.util.EnvUtils;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.io.ByteStreams;
import com.google.zxing.*;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.oned.Code128Writer;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
//import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.krysalis.barcode4j.HumanReadablePlacement;
import org.krysalis.barcode4j.impl.code128.Code128Bean;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

import ink.rayin.htmladapter.base.PdfGenerator;
import ink.rayin.htmladapter.base.Signature;
import ink.rayin.htmladapter.openhtmltopdf.service.PdfBoxGenerator;
import ink.rayin.htmladapter.openhtmltopdf.service.PdfBoxSignature;
import ink.rayin.tools.utils.ResourceUtil;
import java.io.*;
import java.util.List;
import java.util.stream.Collectors;



//import com.be.beadmin.service.util.EnvUtils;

/**
* @author zmy
* @date 2023-05-14
**/
@Api(tags = {"物料管理"})
@RestController
public class PurchaseOrderController {

    @Autowired
    private PurchaseOrderService purchaseOrderService;

    @Autowired
    private WorkOrderInforService workOrderInforService;

    @Autowired
    private WorkOrderInforRepository workOrderInforRepository;

    @Autowired
    private WorkHoursRequestService workHoursRequestService;
    private static final String DEV = "dev";
    static PdfGenerator pdfGenerator;

    static  {
        try {
            pdfGenerator = new PdfBoxGenerator();
//            if (EnvUtils.getENV().contains(DEV)) {
//                pdfGenerator.init();
//            }
//            else {
//                pdfGenerator.init(1,5,15,"/usr/service/sourceCode/fonts");
//            }
//            pdfGenerator.init(1,5,15,"/root/sourceCode/htmlTemp/fonts");

            //使用绝对路径，勿动
            pdfGenerator.init(1,5,15,"/usr/service/sourceCode/fonts");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @ApiOperation("获取所有采购订单")
    @PostMapping(value = "/material/getPurchaseOrderByPage")
    public ResultModel getPurchaseOrderByPage(@RequestBody PageEntity pageEntity)  {
        return ResultModel.success(purchaseOrderService.getPurchaseOrderByPage(pageEntity)) ;
    }
    @ApiOperation("获取缺料采购订单")
    @PostMapping(value = "/material/getPurchaseOrderByPage2")
    public ResultModel getPurchaseOrderByPage2(@RequestBody PageEntity pageEntity)  {
        return ResultModel.success(purchaseOrderService.getPurchaseOrderByPage2(pageEntity)) ;
    }
    @ApiOperation("新建采购订单")
    @PostMapping("/material/addPurchaseOrder")
    public ResultModel addPurchaseOrder(@RequestBody PurchaseOrderDto purchaseOrderDto){
        purchaseOrderService.addPurchaseOrder(purchaseOrderDto);
        return ResultModel.success(ResultModel.ADD);
    }
    @ApiOperation("删除采购订单")
    @PostMapping("/material/delPurchaseOrder")
    public ResultModel delPurchaseOrder(@RequestBody PurchaseOrderDto purchaseOrderDto){
        purchaseOrderService.delPurchaseOrder(purchaseOrderDto.getId());
        return ResultModel.success(ResultModel.DELETE);
    }

    @ApiOperation("更新采购订单")
    @PostMapping("/material/updatePurchaseOrder")
    public ResultModel updatePurchaseOrder(@RequestBody PurchaseOrderDto purchaseOrderDto){
        purchaseOrderService.updatePurchaseOrder(purchaseOrderDto);
        return ResultModel.success(ResultModel.UPDATE);
    }


    @PostMapping("/material/exportPurchaseOrder")
    public void exportPurchaseOrder(HttpServletResponse response ,@RequestBody PageEntity pageEntity) throws IOException {
        Page<PurchaseOrderEx> purchaseOrderPage = purchaseOrderService.getPurchaseOrderByPage(pageEntity);
        List<PurchaseOrderEx> purchaseOrderExes = purchaseOrderPage.getContent();
        List<PurchaseOrderTotalExcelEx> purchaseOrderTotalExcelExes=purchaseOrderExes.stream().map(item->{
            PurchaseOrderTotalExcelEx excel=new PurchaseOrderTotalExcelEx();
            BeanUtils.copyProperties(item,excel);
            return excel;
        }).collect(Collectors.toList());
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("PurchaseOrder接口", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        //EasyExcel.write(response.getOutputStream(), PurchaseOrderTotalExcelEx.class).sheet("sheet1").doWrite(purchaseOrderTotalExcelExes);
        ExcelWriterBuilder ewb=EasyExcel.write(response.getOutputStream(), PurchaseOrderTotalExcelEx.class);
        ewb.excelType(ExcelTypeEnum.XLS);
        ewb.sheet("sheet1").doWrite(purchaseOrderTotalExcelExes);
    }

    @ApiOperation("查询采购订单的详情")
    @PostMapping("/material/getPurchaseOrderDetailByPoId")
    public ResultModel getPurchaseOrderDetailByPoId(@RequestBody PageEntity pageEntity,
                                                    @ApiParam(value = "PurchaseOrderId",required = true) @RequestParam String purchaseOrderId,
                                                    @ApiParam(value = "查询已完成和未完成分料：输入0；只查询已完成分料：输入1；只查询未完成分料：输入2",required = true) @RequestParam int type){

        return ResultModel.success(purchaseOrderService.getPurchaseOrderDetailByPoId(pageEntity,purchaseOrderId,type));
    }
    @ApiOperation("ERP导入订单数据，暂不可用")
    @PostMapping("/material/getPurchaseOrderData")
    public ResultModel getPurchaseOrderData(@ApiParam(value = "订单数据",required = true) @RequestBody ArrayList<PurchaseOrderTotal> purchaseOrderTotal){

        return ResultModel.success();
    }

    //    @ApiOperation("打印工单")
//    @PostMapping("/material/getWorkOrderInfoBarCode")
//    public ResultModel printWorkOrder(@ApiParam(value = "工单数据",required = true) @RequestBody WorkOrderInfor workOrderInfor,
//                                      HttpServletResponse response) throws IOException {
//        String s = workOrderInfor.toString();
//        // 生成条形码
//        Code128Writer code128Writer = new Code128Writer();
//        int marginTop = 10; // 条形码上边距
//        int marginBottom = 5; // 条形码下边距
//
//        BitMatrix bitMatrix = code128Writer.encode(s, BarcodeFormat.CODE_128,300,100 );
//        // 绘制条形码图像
//        BufferedImage image = new BufferedImage(300, 100, BufferedImage.TYPE_INT_RGB);
//        for (int x = 0; x < 300; x++) {
//            for (int y = 0; y < 100; y++) {
//                image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
//            }
//        }
//        // 将图像文件转换为字节数组
//        ByteArrayOutputStream baos = new ByteArrayOutputStream();
//        ImageIO.write(image, "png", baos);
//        byte[] bytes = baos.toByteArray();
//
//        response.addHeader("Accept-Ranges", "bytes");
//        response.addHeader("Content-Disposition", "attachment;filename=barCode.png");
//
//        response.addHeader("Content-Type", "text/plain;charset=utf-8");
//        response.addHeader("Pragma","No-cache");
//        response.addHeader("Cache-Control","No-cache");
//        // 设置HTTP响应头
//        ServletOutputStream os = response.getOutputStream();
//        // 设置HTTP响应头
//        HttpHeaders headers = new HttpHeaders();
//        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//        headers.setContentLength(bytes.length);
//        headers.setContentDispositionFormData("attachment", "barcode.png");
//
//        // 返回HTTP响应
//        return new ResponseEntity<>(bytes, headers, 200);
//    }
    @ApiOperation("打印工单")
    @GetMapping("/material/getWorkOrderInfoBarCode")
    public void printWorkOrder(@ApiParam(value = "工单id，id",required = true) @RequestParam String id,
                                                 HttpServletResponse response) throws IOException {
        //System.out.println(workOrderInfor.toString());
        // 获取工单数据的字符串表示
        WorkOrderInfor workOrderInforById = workOrderInforRepository.findWorkOrderInforById(id);
        String s = workOrderInforById.getWo() ;

        Code128Bean bean = new Code128Bean();
        final int dpi = 100; // 设置图像dpi
        bean.setModuleWidth(0.4);

        bean.setBarHeight(35);
        bean.doQuietZone(true);
        bean.setMsgPosition(HumanReadablePlacement.HRP_NONE);

        boolean antiAlias = false;
        int orientation = 0; // 设置条形码的方向

        // 生成条形码图片
        BitmapCanvasProvider canvas = new BitmapCanvasProvider(response.getOutputStream(), "image/png", dpi, BufferedImage.TYPE_BYTE_BINARY, antiAlias, orientation);
        bean.generateBarcode(canvas, s);

        // 完成条形码的绘制
        canvas.finish();

        // 设置响应头，告诉浏览器以附件形式下载文件
        response.setHeader("Content-Disposition", "attachment; filename=\"barcode.png\"");

        // 关闭响应输出流
        response.getOutputStream().close();


    }
//    @PostMapping(value = "/pack/getPdfByDns")
//    public void getPdfByDns(HttpServletResponse response, @RequestBody DnHeadQueryCriteria pageEntity)  {
////        ResponseUtil.out(response, ResultModel.error(199,"测试接口===>"));
////        String outputFileClass = ResourceUtil.getResourceAbsolutePathByClassPath("./");
//        Page<DnHeadEx> dnHeadExes = dnHeadService.getDnHeadByPage(pageEntity);
//        InputStream inputStream = null;
//
//        ServletOutputStream os = null;
//        try {
//            List<Long> dns = dnHeadExes.stream().map(item -> Long.parseLong(item.getDn())).distinct()
//                    .sorted().collect(Collectors.toList());
//            SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
//
//            SimpleDateFormat dateFormat2 =new SimpleDateFormat("yyyy-MM-dd HH-mm");
//            String pre = dateFormat.format(new Date());
//            String pre2 = dateFormat2.format(new Date());
//            String path = FileToTempPathUtils.pdfToFile(pre);
//            PDFMergerUtility pdfMerger = new PDFMergerUtility();
//            for(Integer i = 0; i < dns.size(); i++) {
//                System.out.println("dn==>" + dns.get(i));
//                StageDetailPdfDetail stageDetailPdfDetail = stageDetailService.getByDn(dns.get(i).toString());
//                JSONObject jsonObject =(JSONObject) JSON.toJSON(stageDetailPdfDetail);
//                String jsonString = jsonObject.toJSONString();
//                System.out.println("JSON对象转换为JSON字符串==>\n" + jsonString);
//
//                String tmpPath = path + dns.get(i)+ ".pdf";
//                File file = new File(path + dns.get(i)+ ".pdf");
//                // 文件如果存在就就用以前的
//                if (file.exists()) {
//                    pdfMerger.addSource(tmpPath);
//// 文件存在，进行操作
//                } else {
//                    if (EnvUtils.getENV().contains(DEV)) {
//                        pdfGenerator.generatePdfFileByHtmlAndData(ResourceUtil.getResourceAbsolutePathByClassPath("pdf/test4dev.html"), jsonObject, tmpPath);
//                    }
//                    else {
//                        pdfGenerator.generatePdfFileByHtmlAndData(ResourceUtil.getResourceAbsolutePathByClassPath("/root/sourceCode/htmlTemp/test.html"), jsonObject, tmpPath);
//                    }
//                    pdfMerger.addSource(tmpPath);
//                }
//            }
////            Thread.sleep(3000);
////
////            File file = new File(path);
////            for (File listFile : file.listFiles()) {
////                pdfMerger.addSource(listFile);
////            }
//            pdfMerger.setDestinationFileName(path + pre2 + ".pdf");
//            pdfMerger.mergeDocuments(null);
////        String outputFile = new File(outputFileClass)
////                .getParentFile().getParent()
////                + "/tmp/"
////                + "example01_openhtmltopdf_"+System.currentTimeMillis() + ".pdf";
//
////            StageOrder stageOrder = new StageOrder();
////            stageOrder.setDn("DN000000001");
////
////            List<StageDetailList> stageDetailListList = new ArrayList<>();
////            for(Integer i = 0; i < 100; i++) {
////                StageDetailList stageDetailList = new StageDetailList();
////                stageDetailList.setBoxId("Box" + i);
////                stageDetailListList.add(stageDetailList);
////            }
////            stageOrder.setStageDetailListList(stageDetailListList);
//            File desFile = new File(path + pre2 + ".pdf");
//            inputStream = new FileInputStream(desFile);
//            response.setCharacterEncoding("utf-8");
//            response.setContentType("application/pdf");
//            os = response.getOutputStream();
//            ByteStreams.copy(inputStream, os);
////            inputStream.close();
//
//        } catch (Exception e) {
//            e.printStackTrace();
//            ResponseUtil.out(response, ResultModel.error(199,e.getMessage()));
//            return;
////
//        } finally {
//            if (inputStream != null) {
//                try {
//                    inputStream.close();
//                } catch (IOException e) {
//                    //log.error(e.getMessage(), e);
//                    ResponseUtil.out(response, ResultModel.error(199,e.getMessage()));
//
//                }
//            }
//            if (os != null) {
//                try {
//                    os.close();
//                } catch (IOException e) {
//                   //log.error(e.getMessage(), e);
//                    ResponseUtil.out(response, ResultModel.error(199,e.getMessage()));
//
//                }
//            }
//        }
////        return ResultModel.success(stageDetailService.getStageDetailByPage(pageEntity)) ;
//    }
//
    @ApiOperation("pdf")
    @GetMapping(value = "/pack/getPdfs")
    public void getPdfByDns(HttpServletResponse response,@RequestParam("ids") List<String> ids)  {
        InputStream inputStream = null;

        ServletOutputStream os = null;
        try {
            //获取工单号
//            List<String> works = id;

            SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat dateFormat2 =new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");

            //将时间转化成字符串序列
            String pre = dateFormat.format(new Date());
            String pre2 = dateFormat2.format(new Date());

            //中间生成的pdf文件存储路径
            String path = "/tmp/tmp/" + pre2;
            PDFMergerUtility pdfMerger = new PDFMergerUtility();

            for(Integer i = 0; i < ids.size(); i++) {
                System.out.println("dn==>" + ids.get(i));
                Map<String, Object> maps = new HashMap<String, Object>();
                WorkOrderInfor workOrderInforById = workOrderInforService.getWorkOrderInforById(ids.get(i));

                //过滤
                maps.put("wo", workOrderInforById.getWo());
                maps.put("projectCode", workOrderInforById.getProjectCode());
                maps.put("projectName", workOrderInforById.getProjectName());
                maps.put("batchCount", workOrderInforById.getBatchCount());
                maps.put("batchPlanCode", workOrderInforById.getBatchPlanCode());
                maps.put("batchProductCode", workOrderInforById.getBatchProductCode());
                if(workOrderInforById.getBatchDeliveryDate() == null)
                    maps.put("batchDeliveryDate", " ");
                else
                    maps.put("batchDeliveryDate", workOrderInforById.getBatchDeliveryDate());

                if(workOrderInforById.getMemo() == null)
                    maps.put("memo", "备注");
                else
                    maps.put("memo", workOrderInforById.getMemo());

                String batchPlanCode = workOrderInforById.getBatchPlanCode();
                String batchProductCode = workOrderInforById.getBatchProductCode();

                String[] splitsBatchProductCode = batchProductCode.split("\\.", 0);
                String[] splits = batchPlanCode.split("\\.", 0);

                List<Float> standardHoursByWo = workHoursRequestService.getStandardHoursByWo(workOrderInforById.getWo());
                Float times = new Float(0);
                for(Integer j = 0; j < standardHoursByWo.size(); j++)
                    times += standardHoursByWo.get(j);

                maps.put("standManufactWorkhour", times);
                maps.put("batch_no", "." + splits[splits.length - 2] + "." + splits[splits.length - 1]);
                Integer lengths = splitsBatchProductCode.length;
                maps.put("productCode", "." + splitsBatchProductCode[lengths - 3] + "." + splitsBatchProductCode[lengths - 2] + "." + splitsBatchProductCode[lengths - 1]);
                maps.put("dn", workOrderInforById.getWo() +  "#" + batchPlanCode + "#" + batchProductCode);
                //过滤结束

                ObjectMapper mapper = new ObjectMapper();
                SimpleModule module = new SimpleModule();
                //将时间再json转化时 转化成字符串序列
                module.addSerializer(Date.class, new CustomDateSerializer());
                mapper.registerModule(module);
                //json字符串
                String json = mapper.writeValueAsString(maps);


//                JSONObject jsonObject =(JSONObject) JSON.toJSON(workOrderInforByWo);
//                JSONObject jsonObject2 =(JSONObject) JSON.toJSON(map);

//                String jsonString = jsonObject.toJSONString();
//                String jsonString2 = jsonObject2.toJSONString();


//                JsonNode jsonNode = mapper.readTree(json);
//                JsonNode jsonNode1 = mapper.readTree(jsonString2);

//                ObjectNode objectNode = mapper.createObjectNode();
//
//                objectNode.setAll((ObjectNode) jsonNode);
//                objectNode.setAll((ObjectNode) jsonNode1);


//                String jsonStringmerge = objectNode.toString();
//                System.out.println(jsonStringmerge);
//                JSONObject jsonObject1 = JSONObject.parseObject(jsonStringmerge);

//                jsonString = json + jsonString2;

                System.out.println("JSON字符串==>\n" + json);
                //String转JSONObject
                JSONObject jsonObject = JSONObject.parseObject(json);
//                String tmpPath = path + works.get(i)+ ".pdf";
                String tmpPath = path + workOrderInforById.getWo() + ".pdf";
                File file = new File(tmpPath);
                // 文件如果存在就就用以前的
                if (file.exists()) {
                    pdfMerger.addSource(tmpPath);
// 文件存在，进行操作
                } else {
//                    if (EnvUtils.getENV().contains(DEV)) {
//                        pdfGenerator.generatePdfFileByHtmlAndData(ResourceUtil.getResourceAbsolutePathByClassPath("pdf/test.html"), jsonObject, tmpPath);
//                    }
//                    else {
//                        pdfGenerator.generatePdfFileByHtmlAndData(ResourceUtil.getResourceAbsolutePathByClassPath("/usr/service/sourceCode/pdf/test.html"), jsonObject, tmpPath);
////                        pdfGenerator.generatePdfFileByHtmlAndData(ResourceUtil.getResourceAbsolutePathByClassPath("/root/sourceCode/htmlTemp/test.html"), jsonObject, tmpPath);
//                    }
                    pdfGenerator.generatePdfFileByHtmlAndData(ResourceUtil.getResourceAbsolutePathByClassPath("/usr/service/sourceCode/pdf/test.html"), jsonObject, tmpPath);
                    pdfMerger.addSource(tmpPath);
                }
            }
//            Thread.sleep(3000);
//
//            File file = new File(path);
//            for (File listFile : file.listFiles()) {
//                pdfMerger.addSource(listFile);
//            }
            pdfMerger.setDestinationFileName("/tmp/tmp/workorder.pdf");
            pdfMerger.mergeDocuments(null);
//        String outputFile = new File(outputFileClass)
//                .getParentFile().getParent()
//                + "/tmp/"
//                + "example01_openhtmltopdf_"+System.currentTimeMillis() + ".pdf";

//            StageOrder stageOrder = new StageOrder();
//            stageOrder.setDn("DN000000001");
//
//            List<StageDetailList> stageDetailListList = new ArrayList<>();
//            for(Integer i = 0; i < 100; i++) {
//                StageDetailList stageDetailList = new StageDetailList();
//                stageDetailList.setBoxId("Box" + i);
//                stageDetailListList.add(stageDetailList);
//            }
//            stageOrder.setStageDetailListList(stageDetailListList);
            File desFile = new File("/tmp/tmp/workorder.pdf");
            inputStream = new FileInputStream(desFile);
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/pdf");
            os = response.getOutputStream();
            ByteStreams.copy(inputStream, os);
//            inputStream.close();

        } catch (Exception e) {
            e.printStackTrace();
            ResponseUtil.out(response, ResultModel.error(199,e.getMessage()));
            return;
//
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    //log.error(e.getMessage(), e);
                    ResponseUtil.out(response, ResultModel.error(199,e.getMessage()));

                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    //log.error(e.getMessage(), e);
                    ResponseUtil.out(response, ResultModel.error(199,e.getMessage()));

                }
            }
        }
//        return ResultModel.success(stageDetailService.getStageDetailByPage(pageEntity)) ;
    }


    public static class CustomDateSerializer extends JsonSerializer<Date> {
        private static final String DATE_FORMAT = "yyyy-MM-dd";

        @Override
        public void serialize(Date value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
            gen.writeString(new java.text.SimpleDateFormat(DATE_FORMAT).format(value));
        }
    }
}